package cz.rosada.sx.library;

import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 * StringUtils is a place for implementing various string utility functions
 * usable throughout the code.
 */
public class StringUtils {

	/**
	 * Universal date time used for data exchange.
	 */
	public static final String UNIVERSAL_DATETIME = "yyyy-MM-dd HH:mm:ss.SSS";

	private static final int MSEC = 1000;

	/**
	 * Removes quotes. i.e. "text" -> text
	 * 
	 * @param string
	 *            text to be unquoted
	 * @return unquoted text
	 */
	public static String unquote(String string) {
		if (string.length() > 0) {
			if (string.charAt(0) == '"') {
				string = string.substring(1);
			}
			if (string.charAt(string.length() - 1) == '"') {
				string = string.substring(0, string.length() - 1);
			}
		}
		return string;
	}

	/**
	 * Removes last '\' separator. i.e. \\hostname\ -> \\hostname
	 * 
	 * @param path
	 *            source text
	 * @return text without separator
	 */
	public static String removeLastSep(String path) {
		if (path.length() > 0 && path.charAt(path.length() - 1) == '\\') {
			return path.substring(0, path.length() - 1);
		}
		return path;
	}

	/**
	 * Return percent representation of current and maximum values i.e.
	 * "30 percent" for parameters 3 and 10.
	 * 
	 * @param current
	 *            Current value. Should be in range <0, maximum>.
	 * @param maximum
	 *            Maximum value. Should be greater that zero otherwise string
	 *            "> percent" is returned.
	 * @return String that represents percentage of current and maximum values.
	 */
	public static String percentageString(int current, int maximum) {
		if (maximum <= 0) {
			return "? percent";
		}
		return Math.round(100 * (double) current / maximum) + " percent";
	}

	/**
	 * Returns text representation of string array. i.e. "a text" or ["one",
	 * "two"] for more then one element.
	 * 
	 * @param strings
	 *            Array that returns as text.
	 * @return Text representation of string array.
	 */
	public static String exportStrings(final String[] strings) {
		StringBuffer result = new StringBuffer();
		if (strings.length == 1) {
			result.append(strings[0]);
			return result.toString();
		}

		result.append("[");
		for (String s : strings) {
			result.append(s + ',');
		}
		result.deleteCharAt(result.length() - 1);
		result.append("]");
		return result.toString();
	}

	/**
	 * Return statistics.
	 * 
	 * @param totalSize
	 * @param time
	 * @return i.e. 2,5MB in 26,222s. (98,7KB/s)
	 */
	public static String performanceString(final long totalSize, final long time) {
		StringBuffer result = new StringBuffer();
		NumberFormat formatter = new DecimalFormat("0.000");
		result.append(bytesToString(totalSize) + " in "
				+ formatter.format((double) time / MSEC) + "s.");
		if (time > 0) {
			long performance = 1000 * totalSize / time;
			result.append(" (" + bytesToString(performance) + "/s)");
		}
		return result.toString();
	}

	public static String bytesToString(long bytes) {
		final long KB = 1024;
		final long MB = KB * KB;
		final long GB = KB * MB;

		NumberFormat formatter;

		if (bytes < KB) {
			formatter = new DecimalFormat("#,##0");
			return formatter.format(bytes) + " B";
		} else if (bytes < MB) {
			formatter = new DecimalFormat("#,##0.#");
			return formatter.format((double) bytes / KB) + "KB";
		} else if (bytes < GB) {
			formatter = new DecimalFormat("#,##0.#");
			return formatter.format((double) bytes / MB) + "MB";
		} else {
			formatter = new DecimalFormat("#,##0.#");
			return formatter.format((double) bytes / GB) + "GB";
		}
	}

	/**
	 * Reduce string length to limit, if string is longed cut it and add "..."
	 * 
	 * @param input
	 *            string
	 * @param limit
	 *            maximum length
	 * @return cutted string
	 */
	public static String limitString(String input, int limit) {
		if (input.length() > limit) {
			return input.substring(1, limit - 3) + "...";
		}
		return input;
	}

	public static byte checksum(final String source) {
		return checksum(source, 1);
	}

	public static byte checksum(final String source, final int fromIndex) {
		byte result = 0;
		for (int i = fromIndex; i < source.length(); i++) {
			byte b = (byte) source.charAt(i);
			result ^= b;
		}
		return result;
	}

	public static int toInt(final String source, final int defaultValue) {
		int result = defaultValue;
		try {
			result = Integer.parseInt(source);
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return result;

	}

}
